package news.utils.httpclient;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.List;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;

import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;

import com.google.common.collect.Lists;
  
public class DefaultRequestRetryHandler implements HttpRequestRetryHandler {  
  
    private int executionCount;  
    List<Class<? extends Exception>> ignoreException;  
    List<Class<? extends Exception>> dealException;  
    public DefaultRequestRetryHandler() {  
        super();  
        Init();  
    }  
  
    @SuppressWarnings("unchecked")  
    public DefaultRequestRetryHandler(int executionCount) {  
        super();  
        this.executionCount = executionCount;  
        ignoreException = (List<Class<? extends Exception>>) (ignoreException.isEmpty()? Lists.newArrayList(ConnectTimeoutException.class,SSLException.class,UnknownHostException.class  
                ,InterruptedIOException.class,SSLHandshakeException.class): ignoreException);  
        dealException = (List<Class<? extends Exception>>) (dealException.isEmpty()? Lists.newArrayList(NoHttpResponseException.class): dealException);  
    }  
  
    @SuppressWarnings("unchecked")  
    public DefaultRequestRetryHandler(int executionCount, List<Class<? extends Exception>> ignoreException) {  
        super();  
        this.executionCount = executionCount;  
        this.ignoreException = ignoreException;  
        dealException = (List<Class<? extends Exception>>) (dealException.isEmpty()? Lists.newArrayList(NoHttpResponseException.class): dealException);  
    }  
  
    public DefaultRequestRetryHandler(int executionCount, List<Class<? extends Exception>> ignoreException,  
            List<Class<? extends Exception>> dealException) {  
        super();  
        this.executionCount = executionCount;  
        this.ignoreException = ignoreException;  
        this.dealException = dealException;  
    }  
  
    @SuppressWarnings("unchecked")  
    private void Init() {  
        executionCount = executionCount <= 0 ? 5 : executionCount;  
        ignoreException = (List<Class<? extends Exception>>) ((ignoreException == null ||ignoreException.isEmpty())? Lists.newArrayList(ConnectTimeoutException.class,SSLException.class,UnknownHostException.class  
                ,InterruptedIOException.class,SSLHandshakeException.class): ignoreException);  
        dealException = (List<Class<? extends Exception>>) ((dealException ==null || dealException.isEmpty())? Lists.newArrayList(NoHttpResponseException.class): dealException);  
    }  
  
    @Override  
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {  
        if (executionCount >= this.executionCount) {  
            return false;  
        }  
        for (Iterator<Class<? extends Exception>> iterator = ignoreException.iterator(); iterator.hasNext();) {  
            Class<? extends Exception> clazz = (Class<? extends Exception>) iterator.next();  
            if (exception.getClass().isAssignableFrom(clazz)) {  
                return false;  
            }  
        }  
        for (Iterator<Class<? extends Exception>> iterator = dealException.iterator(); iterator.hasNext();) {  
            Class<? extends Exception> clazz = (Class<? extends Exception>) iterator.next();  
            if (exception.getClass().isAssignableFrom(clazz)) {  
                return true;  
            }  
        }  
        exception.printStackTrace();  
        return false;  
    }  
}  
